<template>
    <div class="assignTemplate">
      <div class="transferBox">
        <div class="permission-tree-container">
          <el-input style="margin-bottom:10px"
                    placeholder="搜索分类"
                    prefix-icon="el-icon-search"
                    v-model="filterText">
          </el-input>
          <p class="tips">温馨提示：树形可通过鼠标右键维护</p>
          <div style="height:400px;overflow-y:auto;">
            <el-tree class="treeShow"
                     :data="permissionTree"
                     :props="defaultProps"
                     label="object_name"
                     node-key="object_id"
                     ref="permissionList"
                     :highlight-current="true"
                     :filter-node-method="filterNode"
                     @node-contextmenu="rihgtClick"
                     @node-click="getId"
                     draggable
                     :default-expanded-keys="selectedNodeList"
                     :default-checked-keys="checkedNodeList"
                     :accordion="false"
                     :auto-expand-parent="false"
                     :check-strictly="true">
              <span class="slot-t-node"
                    slot-scope="{ node, data }">
                <span v-show="!node.isEdit">
                  <span v-show="data.children_list && data.children_list.length >= 1">
                    <!-- <i :class="{'el-icon-time':node.level<=1,'el-icon-bell':node.level>1&&node.level<=2,'el-icon-service':node.level>2}" /> -->
                    <i :class="{ 'el-icon-plus':!node.expanded,'el-icon-minus':node.expanded}" />
                    <span :class="[data.id >= maxexpandId ? 'slot-t-node--label' : '']"
                          :title="data.system_name||data.object_name">{{data.system_name || data.object_name}}</span>
                  </span>
                  <!-- 当树形节点不存在子节点时，设置单独的图标 -->
                  <span v-show="!data.children_list || data.children_list.length == 0">
                    <i class="el-icon-document"></i>
                    <span :class="[data.id >= maxexpandId ? 'slot-t-node--label' : '']"
                          :title="data.system_name||data.object_name">{{data.system_name || data.object_name}}</span>
                  </span>
                </span>
                <!-- 编辑输入框 -->
                <span v-show="node.isEdit">
                  <el-input class="slot-t-input"
                            size="mini"
                            autofocus
                            v-model="data.name"
                            :ref="'slotTreeInput'+data.id"
                            @blur.stop="NodeBlur(node, data)"
                            @keyup.enter.native="NodeBlur(node, data)"></el-input>
                </span>
              </span>
            </el-tree>
          </div>
  
          <!--鼠标右键点击出现页面-->
          <div v-show="menuVisible">
            <el-menu id="rightClickMenu"
                     class="el-menu-vertical"
                     @select="handleRightSelect"
                     active-text-color="#fff"
                     text-color="#fff">
              <!-- 根据不同的状态，显示不同的右键自定义菜单（岗位与非岗位状态） -->
              <el-menu-item index="1"
                            class="menuItem">
                <i class="el-icon-plus"
                   style="color:#fff" />
                <span slot="title"
                      @click="onAdd">新增</span>
              </el-menu-item>
              <el-menu-item index="2"
                            v-if="DATA.object_id"
                            class="menuItem">
                <i class="el-icon-edit"
                   style="color:#fff" />
                <span slot="title"
                      @click="onEdit">修改</span>
              </el-menu-item>
              <el-menu-item index="3"
                            v-if="DATA.object_id"
                            class="menuItem">
                <i class="el-icon-delete"
                   style="color:#fff" />
                <span slot="title">删除</span>
              </el-menu-item>
  
            </el-menu>
          </div>
          <!-- 新增或修改子节点    :title="judge==1?'新增权限项':'修改权限项'"-->
          <el-dialog :visible.sync="addSonUnitDialog"
                     :close-on-click-modal="false"
                     :title="judge==1?'新增权限项':'修改权限项'"
                     width="45%"
                     append-to-body>
            <el-form :model="sonUnitform"
                     :inline="true">
              <el-form-item label="权限编号">
                <el-input v-model="sonUnitform.object_no"
                          autocomplete="off"
                          :disabled="addOrEdit==='edit'"
                          placeholder="请输入权限编号"></el-input>
              </el-form-item>
              <el-form-item label="权限名称">
                <el-input v-model="sonUnitform.object_name"
                          autocomplete="off"
                          style="float:right;"
                          placeholder="请输入权限名称"></el-input>
              </el-form-item>
  
            </el-form>
            <div style="text-align:center;">
              <el-button type="primary"
                         @click="addSonUnitDialog= false"
                         id="save-style">返 回</el-button>
              <el-button @click="addPermissionTreeNode"
                         id="back-style">保 存</el-button>
            </div>
          </el-dialog>
        </div>
        <div class="tableBox">
          <el-table ref="menuTable"
                    @current-change="handleMenuChange"
                    :data="permissionData.list"
                    :row-key="(row) => row.object_id"
                    :highlight-current-row="true"
                    :header-cell-style="{background:'#f5f5f5'}"
                    @selection-change="handleSelectionChange"
                    @select="changeCheck"
                    @select-all="changeAll"
                    default-expand-all
                    height="500px"
                    border>
            <el-table-column type="selection"
                             :reserve-selection="true"
                             width="55">
            </el-table-column>
            <el-table-column type="index"
                             label="序号"
                             sortable
                             align="center"
                             width="100"
                             show-overflow-tooltip>
            </el-table-column>
            <el-table-column prop="object_name"
                             label="权限名称"
                             align="center"
                             show-overflow-tooltip>
            </el-table-column>
            <el-table-column prop="object_sort_name"
                             label="类型"
                             align="center"
                             show-overflow-tooltip>
            </el-table-column>
          </el-table>
  
          <el-pagination id="pagination"
                         background
                         @current-change="handleSizeChange"
                         :current-page="requestParam.page"
                         :page-size="requestParam.page_size"
                         layout="total, prev, pager, next, jumper"
                         :total="permissionData.total_count">
          </el-pagination>
        </div>
      </div>
    </div>
  </template>
  
  <script>
  // import MenuTree from '@/components/MenuTree/MenuTree'
  import { menuManageApi, permissionManageApi } from '@/services/PermissionManage'
  
  export default {
    data () {
      return {
        permissionData: { // 权限列表数据
          list: [],
          total_count: 0,
          total_page: 0
        },
        judge: '', // 新增/修改
        info: this.messageinfo,
        work: false,
        filterText: '',
        addSonUnitDialog: false,
        addDepDialog: false,
        addJobDialog: false,
        DATA: {},
        NODE: {},
        maxexpandId: 95, // 新增节点开始id
        non_maxexpandId: 95, // 新增节点开始id(不更改)
        isLoadingTree: true, // 是否加载节点树
        //   setTree:api.treelist,//节点树数据
        defaultProps: {
          children: 'children',
          label: 'object_name'
        },
        menuVisible: false,
        objectID: null,
        // 子单位
        sonUnitform: {
          object_name: '',
          object_no: '',
          object_id: '',
  
          p_object_no: ''
        },
        // 编辑或新增
        addOrEdit: 'add',
        // 部门
        departmentForm: {
          name: '',
          tips: ''
        },
        // 岗位
        JobForm: {
          name: '',
          tips: ''
        },
        permissionTreeParam: {
          type: 'dir'
        },
        permissionTreeData: [],
        deletePermissionTreeParam: {
  
        },
        // 选中的权限列表
        assignPermissionList: [],
        // 选中的节点列表，用于刷新后展开到指定位置
        selectedNodeList: [],
        // 选中的节点列表，用于选中复选框
        checkedNodeList: [],
        arrId: [],
  
        currentRowRight: null,
        requestParam: {
          object_no: '',
          object_name: '',
          is_page: 1,
          page: 1,
          page_size: 10
        },
        checkIds: [], //默认选择的编号
        totalArr: [], //最终选择的编号
        permissionNo: {}, // 选中的权限编号
        permissionTreeData: [],// 权限树数据
        selArrs: [],
      }
    },
    props: {
      curPermissionNo: Object,  //父向子传值
      curPermissionIds: Array,
      isVisible: Boolean
    },
    created () {
      // this.getPermissionList()
  
      let storage = window.localStorage.getItem('permissionTree') //存在本地的树
      this.checkedNodeList = []
      this.selectedNodeList = []
      if (!storage) {  //不存在的话重新调取函数
        this.getPermissionTreeData()
      }
  
    },
    mounted () {
      //页面刚加载的时候初始化totalArr
      this.defaultIds = this.checkedNodeList
      let newArr = [...this.defaultIds, ...this.checkIds] //合并回显的选中id和后来新选中的
      newArr = Array.from(new Set(newArr))
      this.totalArr = newArr
    },
    methods: {
      handleSizeChange (page) {
        this.requestParam.page = page
        this.getPermissionList()
      },
      onAdd () {
        this.judge = 1
      },
      onEdit () {
        this.judge = 2
      },
      // 节点点击事件获取id
      getId (data, node) {  //获取当前点击数
        let curData = JSON.parse(JSON.stringify(data))
        // console.log(curData, "当前选中的data");
        this.menuVisible = false
        if ((node.expanded || node.childNodes.length === 0) && data.object_id) {
          this.addNodeList(data.object_id)
        } else {
          this.removeNodeList(data.object_id)
        }
        if (curData.object_no) {
          this.permissionNo = curData
          // this.$emit('update:curPermissionNo', curData)
        }
        // console.log(this.selectedNodeList, 'selected node list')
      },
      // 当当前节点是展开操作时,将当前节点的object_id添加到selectedNodeList中，为了刷新数据后能够展开到指定位置
      addNodeList (objectId) {
        let index = this.selectedNodeList.indexOf(objectId)
        if (index < 0) {
          this.selectedNodeList.push(objectId)
        }
      },
      // 当前节点是收起操作时，将当前节点的object_id从selectedNodeList中移除
      removeNodeList (objectId) {
        let index = this.selectedNodeList.indexOf(objectId)
        if (index >= 0) {
          this.selectedNodeList.splice(index, 1)
        }
      },
      // 对树节点进行筛选时执行的方法，返回 true 表示这个节点可以显示，返回 false 则表示这个节点会被隐藏
      filterNode (value, data) {
        if (!value) return true
        if (data.object_name) {
          return data.object_name.indexOf(value) !== -1
        } else {
          return data.system_name.indexOf(value) !== -1
        }
      },
      // 右键弹出的菜单点击事件
      handleRightSelect (key) {
        // console.log(key === 1)
        if (key == 1) {
          this.NodeAdd(this.NODE, this.DATA)
          this.menuVisible = false // 关闭右键打开的操作菜单
        } else if (key == 2) {
          this.NodeEdit(this.NODE, this.DATA)
          this.menuVisible = false
        } else if (key == 3) {
          this.NodeDel(this.NODE, this.DATA)
          this.menuVisible = false
        } else if (key == 4) {
          this.menuVisible = false
          this.addSonUnitDialog = true
        } else if (key == 5) {
          this.menuVisible = false
          this.addDepDialog = true
        } else if (key == 6) {
          this.menuVisible = false
          this.addJobDialog = true
        }
      },
      NodeBlur (n, d) {
        // 输入框失焦
        if (n.isEdit) {
          this.$set(n, 'isEdit', false)
        }
        this.$nextTick(() => {
          this.$refs['slotTreeInput' + d.id].$refs.input.focus()
        })
      },
      NodeEdit (n, d) {
        // console.log(n, d);
        this.judge = 2
        this.addOrEdit = 'edit'
        this.addSonUnitDialog = true
        this.sonUnitform.object_name = d.object_name
        this.sonUnitform.object_no = d.object_no
        this.sonUnitform.p_object_no = d.p_object_no
        this.sonUnitform.object_id = d.object_id
        this.sonUnitform.system_no = d.system_no
      },
      NodeDel (n, d) {
        // 删除节点
        if (d.children && d.children.length !== 0) {
          this.$message.error('此权限项有子级，不可删除！')
          return false
        } else {
          // 新增节点可直接删除，已存在的节点要二次确认
          // 删除操作
          let DelFun = () => {
            let _list = n.parent.data.children || n.parent.data // 节点同级数据
            let _index = _list.map(c => c.id).indexOf(d.id)
            _list.splice(_index, 1)
            this.$message.success('删除成功！')
          }
          // 二次确认
          let ConfirmFun = () => {
            this.$confirm('是否删除此权限项？', '提示', {
              confirmButtonText: '确认',
              cancelButtonText: '取消',
              type: 'warning'
            })
              .then(() => {
                this.deletePermissionTreeParam.object_id = d.object_id
                this.deletePermissionTreeParam.object_no = d.object_no
                this.deletePermissionTreeParam.system_no = d.system_no
                this.deletePermissionTreeNode()
              })
              .catch(() => { })
          }
          // 判断是否是新增节点
          d.id > this.non_maxexpandId ? DelFun() : ConfirmFun()
        }
      },
      NodeAdd (n, d) {
        // 新增节点
        // console.log(n, d)
        this.judge = 1
        this.addOrEdit = 'add'
        this.sonUnitform = {}
        this.sonUnitform.p_object_no = d.object_no
        this.sonUnitform.system_no = d.system_no
        this.addSonUnitDialog = true
      },
      // 右键点击事件
      rihgtClick (event, object, value, element) {
        this.DATA = object
        this.NODE = value
        this.menuVisible = !this.menuVisible
        document.addEventListener('click', e => {
          this.menuVisible = false
        })
        let menu = document.querySelector('#rightClickMenu')
        /* 菜单定位基于鼠标点击位置 */
        menu.style.left = event.clientX + 20 - 200 + 'px'
        menu.style.top = event.clientY - 15 + 'px'
        menu.style.position = 'absolute' // 为新创建的DIV指定绝对定位
        menu.style.width = 160 + 'px'
      },
      handelData (treeData) {
        // console.log(treeData);
        this.checkedNodeList = []
        let data = this.mapData(treeData)
        return data
      },
      // 处理传入的数据，因为后端都是children_list，需要手动赋值一个children字段
      mapData (arr, pId) {
        if (Object.prototype.toString.call(arr) === '[object Array]') {
          arr.map((item) => {
            // console.log(item);
            // 除目录级别权限，即is_dir为1，都可以选择
            // if (item.object_no !== '' && !item.sid) {\
            if (item.is_dir === '0') {
              item.disabled = false
            } else {
              item.disabled = true
            }
            if (item.sid) {
              item.object_id = item.sid + item.system_no
            }
            if (item.object_id === '') {
              item.object_id = '0'
            }
            if (pId) {
              item.p_object_id = pId
              this.arrId.push(item.object_id)
            }
            // 判断当前权限项是否选中
            if (item.is_select === 1) {
              if (!this.checkedNodeList.includes(item.object_id)) {
                this.checkedNodeList.push(item.object_id)
              }
            }
            if (item.children_list) {
              item.children = item.children_list
              // pId = item.object_id
              this.mapData(item.children_list, item.object_id)
            }
          })
          // console.log(this.checkedNodeList, "选中列表");
          return arr
        }
  
      },
      // 调用权限项分类新增或编辑接口
      addPermissionTreeNode () {
        if (this.addOrEdit === 'add') {
          permissionManageApi.addPermissionTreeClass({
            data: this.sonUnitform
          }).then(res => {
            // console.log(res, 'add permission class')
            if (res.code === 0) {
              this.$message.success('新增权限项分类成功')
              this.addSonUnitDialog = false
              this.getPermissionTreeData()
            }
          })
        } else {
          permissionManageApi.editPermissionTreeClass({
            data: this.sonUnitform
          }).then(res => {
            // console.log(res, 'edit permission class')
            if (res.code === 0) {
              this.$message.success('修改权限项分类成功')
              this.addSonUnitDialog = false
              this.getPermissionTreeData()
            }
          })
        }
      },
      // 删除权限项分类
      deletePermissionTreeNode () {
        permissionManageApi.deletePermissionTreeClass({
          data: this.deletePermissionTreeParam
        }).then(res => {
          if (res.code === 0) {
            this.$message.success('删除权限成功')
            this.getPermissionTreeData()
          }
        })
      },
      //表格选择
      handleSelectionChange (data) {
        // this.$emit('update:curPermissiontable', data[0])
        this.checkIds = []
        data.forEach(item => {
          this.checkIds.push(item.object_id)
          this.checkIds = Array.from(new Set(this.checkIds))
          //去重
        });
        this.totalArr.push(...this.checkIds)
        this.totalArr = Array.from(new Set(this.totalArr))
        // console.log(this.checkIds.length, '编号id长度');
        this.$emit('update:curPermissionIds', this.totalArr)
      },
      //点击取消选中
      changeCheck (selection, row) {
        let selected = selection.length && selection.indexOf(row) !== -1;
        // console.log(selected);
        //selected是当前点击的选中态
        if (selected === false || selected === 0) {
          this.$nextTick(() => {
            this.$refs.menuTable.selection.forEach((ele) => {
              if (ele.object_id == row.object_id) {
                this.$refs.menuTable.toggleRowSelection(ele, false);
              }
            });
            let index = this.totalArr.indexOf(row.object_id)
            this.totalArr.splice(index, 1)
            // console.log(this.totalArr.length);
            this.$emit('update:curPermissionIds', this.totalArr)
          });
        }
      },
      setChildren (children, type) {
        // 编辑多个子层级
        children.map((j) => {
          this.toggleSelection(j, type)
          if (j.children) {
            this.setChildren(j.children, type)
          }
        })
      },
      //是否选中状态
      toggleSelection (row, select) {
        if (row) {
          this.$nextTick(() => {
            this.$refs.menuTable && this.$refs.menuTable.toggleRowSelection(row, select)
          })
        }
      },
      //全选,选中子权限项
      changeAll (selection) {
        let selArr = []
        // 第一层只要有在selection里面就是全选
        const isSelect = selection.some((el) => {
          const tableDataIds = this.permissionData.list.map((j) => j.object_id)
          return tableDataIds.includes(el.object_id)
        })
        //第一层只要有不在selection里面就是全不选
        const isCancel = !this.permissionData.list.every((el) => {
          const selectIds = selection.map((j) => j.object_id)
          return selectIds.includes(el.object_id)
        })
        // console.log(isSelect, 'isSelect')
        if (isSelect) {
          selection.map((el) => {
            if (el.children) {
              // 解决子组件没有被勾选到
              this.setChildren(el.children, true)
            }
          })
          let childIds = []
          selection.map(item => {
            selArr.push(item.object_id);
            if (item.children) {
              item.children.map((j) => {
                childIds.push(j.object_id)
              })
              this.selArrs = selArr.concat(childIds)
            }
          })
        }
        if (isCancel) {
          this.permissionData.list.map((el) => {
            if (el.children) {
              // 解决子组件没有被勾选到
              this.setChildren(el.children, false)
            }
          })
          this.selArrs.forEach(item => {
            let index = this.totalArr.indexOf(item)
            if (index !== -1) {
              this.totalArr.splice(index, 1)
            }
          })
          // console.log(this.totalArr.length, '取消某一个');
          this.$refs.menuTable.clearSelection()
        }
        this.$emit('update:curPermissionIds', this.totalArr)
      },
      //刚加载的时候
      getChecked (tableData) {
        tableData.forEach(row => {
          //把子权限id找出来
          if (row.children_list) {
            this.getChecked(row.children_list)
          }
          if (row.object_id) {
            this.$nextTick(() => {
              this.totalArr.forEach(item => { //表格默认选中,选中回显
                if (item === row.object_id) {
                  this.$refs.menuTable.toggleRowSelection(row, true);
                }
              })
            })
          }
        })
        // console.log(this.totalArr.length, '翻页');
        return tableData
      },
      // 获取页面菜单列表 表格
      getPermissionList () {
        permissionManageApi.getPermissionList({
          params: this.requestParam
        }).then(res => {
          this.$refs.menuTable.clearSelection() //翻页的时候清空,防止没有选择项全选却选中了
          this.permissionData = res.data
          this.permissionData.list.map((item) => {
            this.selArrs.push(item.object_id)
            item.children = item.children_list || []
            item.children.map((childItem) => {
              childItem.p_object_name = item.object_name
              this.selArrs.push(childItem.object_id)
            })
          })
          this.selArrs = Array.from(new Set(this.selArrs))
          // console.log(this.selArrs, '全选取消的时候用');
          if (this.permissionData.list.length != 0) {
            this.setCurrent(this.permissionData.list[0])  //表格高亮
          }
          this.getChecked(this.permissionData.list)
        })
      },
      // 背景色
      handleMenuChange (val) {
        this.currentRowRight = val
      },
      setCurrent (row) {  //首行高亮
        this.$refs.menuTable.setCurrentRow(row);
      },
      // 获取权限树数据
      getPermissionTreeData () {
        permissionManageApi.getPermissionTreeData({
          params: this.permissionTreeParam
        }).then(res => {
          this.permissionTreeData = res.data
          this.$store.dispatch('setPermissionTree', this.permissionTreeData)
          window.localStorage.setItem('permissionTree', JSON.stringify(this.permissionTreeData))
        })
      }
    },
    computed: {
      permissionTree () {
        let store = this.$store.state.permissionTree
        let storage = JSON.parse(window.localStorage.getItem('permissionTree')) || []
        let treeData = store.length > 0 ? store : storage
        // if (treeData.object_name) {
        //   treeData.object_id = '0'
        // }
        treeData = this.handelData([treeData])
        // console.log(treeData, 'treedata')
        return treeData
      }
    },
    watch: {
      filterText (val) {
        this.$refs.permissionList.filter(val)
      },
      messageinfo (newValue, oldValue) {
        this.info = newValue
        // console.log('===', newValue)
      },
      isVisible: {  //打开分配权限弹窗时
        handler (newval, oldval) {
          if (newval) {
            this.$refs.menuTable.clearSelection() //先把之前的选中项都清空
            setTimeout(() => {
              // console.log(this.checkedNodeList, '新的窗口的');
              // 重新打开的时候恢复本来的选项
              this.defaultIds = this.checkedNodeList
              this.checkIds = [] //清空新添加的选项
              let newArr = [...this.defaultIds, ...this.checkIds] //合并回显的选中id和后来新选中的
              newArr = Array.from(new Set(newArr))
              this.totalArr = newArr
              this.getChecked(this.permissionData.list) //重新回显
            }, 500);
          }
        },
        deep: true
      },
      permissionNo: {
        handler (newval, oldval) {
          this.requestParam.object_no = newval.object_no;
          this.requestParam.system_no = newval.system_no;
          this.requestParam.page = 1 //点击第二页再点击菜单,分页高亮是1,内容是第二页
          // console.log(this.requestParam.page);
          this.getPermissionList();
        },
        deep: true
      }
    }
  }
  </script>
  
  <style lang="scss" scoped>
  #save-style {
    background: rgba(26, 188, 156, 1);
  }
  #back-style {
    color: white;
    background: rgba(26, 188, 156, 1);
  }
  .el-pagination {
    text-align: center;
  }
  .popover-new {
    /* position: absolute!important;
      right: 0;
      bottom: 0; */
  }
  /*顶部按钮*/
  .slot-tree .slot-t-top {
    margin-bottom: 15px;
  }
  .slot-tree .slot-t-node span {
    display: inline-block;
  }
  /*节点*/
  .slot-tree .slot-t-node--label {
    font-weight: 600;
  }
  /*输入框*/
  .slot-tree .slot-t-input .el-input__inner {
    // height: 26px;
    // line-height: 26px;
  }
  /*按钮列表*/
  .slot-tree .slot-t-node .slot-t-icons {
    display: none;
    margin-left: 10px;
  }
  .slot-tree .slot-t-icons .el-button + .el-button {
    margin-left: 6px;
  }
  .slot-tree .el-tree-node__content:hover .slot-t-icons {
    display: inline-block;
  }
  
  /*************************标签鼠标右击页面样式******************************/
  .el-menu-vertical {
    border: 3px solid rgb(84, 92, 100);
    border-radius: 10px;
    z-index: 100;
  }
  .el-menu-vertical i {
    color: #777777;
  }
  .menuItem {
    height: 40px;
    line-height: 40px;
    background-color: #545c64;
    font-size: 1.2rem;
  }
  .menuItem:hover {
    background-color: #409eff;
  }
  .add_tips /deep/ .el-form-item__label {
    padding-left: 28px;
  }
  .permission-tree-container {
    width: 300px;
    .el-tree {
      min-height: 300px;
      height: auto;
    }
    .tips {
      color: #9e9e9e;
      margin-bottom: 10px;
      text-align: center;
    }
  }
  
  .assignTemplate {
    .transferBox {
      display: flex;
      justify-content: space-around;
      .tableBox {
        width: 60%;
      }
    }
  }
  //表格选中行hover颜色修改
  /deep/ .el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell {
    background-color: #f5f7fa;
    color: #606266;
  }
  /deep/ .el-table__body tr:hover.current-row > td .el-button {
    color: #66b1ff;
  }
  </style>
  